﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using UCL.Powersource;
using UCL.Powersource.Analysis;
using UCL.Powersource.TFS;

namespace UCL.Powersource.Mock
{
    [DataContract]
    public class DummyTeamProjectCollectionConfiguration : PropertyChangedInitializedLifeCycle, ITfsTeamProjectCollectionConfiguration
    {

        private ILog _Log;
        public ILog Log { get { return _Log ?? (_Log = LogManager.GetLog(typeof(DummyTeamProjectCollectionConfiguration))); } }

        protected override bool OnInitializing()
        {
            if (_AllReportingContextCollection == null)
            {
                _AllReportingContextCollection = new ObservableCollection<ReportingContext>(ReportingContext.CreateDefaults(this));
            }
            return true;
        }

        protected override void OnDisposing()
        {
            return;
        }


        public DummyTeamProjectCollectionConfiguration()
        {
            TeamProjectConfigurations = new List<ITfsTeamProjectConfiguration>();

            var r1 = new Guid("92BF93D9-687D-403A-865F-BDABBD26A6D0");
            var r2 = new Guid("88B8D221-FF6F-4AEC-ACAA-8383C2982570");
            var r3 = new Guid("15AD6FC1-CDCC-4FDC-8443-91EE0D655193");
            var r4 = new Guid("047CDF9D-8CB0-49D9-848C-E10D54E7028F");
            var r5 = new Guid("2BF637CF-AB5A-48CB-B1F4-7C1DA3155FC7");
            TeamProjectConfigurations.Add(new DummyTeamProjectConfiguration("TestProject1", 1, this, r1) { IsChosen = true });
            TeamProjectConfigurations.Add(new DummyTeamProjectConfiguration("TestProject2", 2, this, r2) { IsChosen = true });
            TeamProjectConfigurations.Add(new DummyTeamProjectConfiguration("TestProject3", 3, this, r3) { IsChosen = true });
            TeamProjectConfigurations.Add(new DummyTeamProjectConfiguration("TestProject4", 4, this, r4) { IsChosen = true });
            TeamProjectConfigurations.Add(new DummyTeamProjectConfiguration("TestProject5", 5, this, r5));

            _ProjectCollectionTimeFrames = new List<ITimeFrame>();
            _ProjectCollectionTimeFrames.Add(new DummyTimeframe("Release1\\Sprint1", new DateTime(2012, 1, 1)));
            _ProjectCollectionTimeFrames.Add(new DummyTimeframe("Release1\\Sprint2", new DateTime(2012, 1, 8)));
            _ProjectCollectionTimeFrames.Add(new DummyTimeframe("Release2\\Sprint1", new DateTime(2012, 1, 15)));



        }

        [DataMember]
        private string _Uri;

        public string Uri
        {
            get { return TfsTeamProjectCollection.Uri.ToString(); }
            set { _Uri = value; }
        }
        [DataMember]
        public List<ITimeFrame> _ProjectCollectionTimeFrames;
        [DataMember]
        public List<ITfsTeamProjectConfiguration> TeamProjectConfigurations;
        [IgnoreDataMember]
        private ITfsTeamProjectCollection _TfsTeamProjectCollection;
        [IgnoreDataMember]
        public ITfsTeamProjectCollection TfsTeamProjectCollection { get { return _TfsTeamProjectCollection; } set { _TfsTeamProjectCollection = value; } }
        [IgnoreDataMember]
        
        public IEnumerable<ITimeFrame> ProjectCollectionTimeFrames
        {
            get { return _ProjectCollectionTimeFrames; }
        }



        [IgnoreDataMember]
        public string Label
        {
            get { return Name; }
        }

        public IEnumerator<ITfsTeamProjectConfiguration> GetEnumerator()
        {
            return TeamProjectConfigurations.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return TeamProjectConfigurations.GetEnumerator();
        }
        [DataMember]
        
        private string _Name = "DummyTeamProjectCollection";

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        [DataMember]
        public string IldasmPath { get; set; }
        [DataMember]
        public string MSBuildPath
        {
            get;
            set;
        }
        [DataMember]
        public string LocalDropBasePath
        {
            get;
            set;
        }
        [DataMember]
        public string CodeIndexDBServer
        {
            get;
            set;
        }
        [DataMember]
        public string ExportPath
        {
            get;
            set;
        }
        [DataMember]
        public string WebServiceUrl
        {
            get;
            set;
        }




        /// <summary>
        /// This function resets AllReportingContextCollection. It creates new one and inserts 1 default reportinitem 
        /// </summary>
        private void AllReportingContextCollection_Merge()
        {
            if (!IsInitialized) Initialize();
            //Synchornizing ReportingContext
            if (_AllReportingContextCollection == null)
                throw new InvalidOperationException("_AllReportingContextCollection should never be set to null. Internal error");
            else
            {


                List<ReportingContext> listofRCToDelete = new List<ReportingContext>();
                //Invalid reporting context will be marked to delete and remove afterwards
                //Valid reporting context will be merged
                foreach (var rc in _AllReportingContextCollection)
                {
                    if (rc.TfsTeamProjectCollectionConfiguration != this)
                    {
                        var oldTfsTPCC = rc.TfsTeamProjectCollectionConfiguration;
                        string oldTfsTPCCURI = "#NULL";
                        if (oldTfsTPCC != null) oldTfsTPCCURI = rc.TfsTeamProjectCollectionConfiguration.Uri;
                        Log.Error(null, "Ignored Reporitng context! There is a reporting context in {0} {1} which has different {0} assigned. Actual value is {2}", this.GetType().Name, this.Uri, oldTfsTPCCURI);
                        listofRCToDelete.Add(rc);
                    }
                    else
                    {
                        rc.Initialize();
                    }
                }
                //Remove them now
                foreach (var rcToDelete in listofRCToDelete)
                {
                    _AllReportingContextCollection.Remove(rcToDelete);
                }

                //if list of available AllReportingContextCollection is empty add new null one and merge

                if (_AllReportingContextCollection.Count == 0)
                {
                    // if there is no reporting context create default one
                    var rcs = ReportingContext.CreateDefaults(this);
                    foreach (var rc in rcs)
                    {
                        _AllReportingContextCollection.Add(rc);
                    }
                    
                }

            }

        }

        private void Merge()
        {
            AllReportingContextCollection_Merge();
        }

        public void Synchronize()
        {
            Merge();
        }

        public bool IsConnectedTo(ITfsTeamProjectCollection CurrentTfsTeamProjectCollection)
        {
            return TfsTeamProjectCollection == CurrentTfsTeamProjectCollection;
        }


        #region AllReportingContextCollection

        /// <summary>
        /// Field storage for property AllReportingContextCollection
        /// </summary>
        [DataMember]
        private ObservableCollection<ReportingContext> _AllReportingContextCollection = default(ObservableCollection<ReportingContext>);

        /// <summary>
        /// Property AllReportingContextCollection. TODODOC: Insert appropriate summary here
        /// </summary>
        public ObservableCollection<ReportingContext> AllReportingContextCollection
        {
            get { return _AllReportingContextCollection; }
        }

        #endregion

        #region CurrentReportingContext

        /// <summary>
        /// Field storage for property CurrentReportingContext
        /// </summary>
        private ReportingContext _CurrentReportingContext = default(ReportingContext);

        /// <summary>
        /// Property CurrentReportingContext. TODODOC: Insert appropriate summary here
        /// </summary>
        public ReportingContext CurrentReportingContext
        {
            get { return _CurrentReportingContext; }
            set { if (_CurrentReportingContext == value) return; _CurrentReportingContext = value; CurrentReportingContext_RecalculateDependencies(); }
        }

        private void CurrentReportingContext_RecalculateDependencies()
        {
            //Recalculate all properties here

            //NotifyOfPropertyChange is usually placed as last statement - first change all dependencies and then fire property change
            NotifyOfPropertyChange(() => CurrentReportingContext);
        }

        private void CurrentReportingContext_Recalculate()
        {
            _CurrentReportingContext = default(ReportingContext);
            //Insert your code here

            CurrentReportingContext_RecalculateDependencies();
        }

        #endregion



        public string DefaultProjectName
        {
            get
            {
                return CalculateDefaultProjectName();
            }
            set
            {
                DefaultProjectName = value;
            }
        }

        public string CalculateDefaultProjectName()
        {
            if (TeamProjectConfigurations.Count > 1)
                return this.First().UniqueName;
            else return "";
        }
    }
}
